```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Spring 拦截链 | 技术小馆</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            line-height: 1.6;
            color: #333;
            background-color: #f8f9fa;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%);
        }
        .code-block {
            font-family: 'Courier New', Courier, monospace;
            background-color: #1e1e1e;
            color: #d4d4d4;
            border-radius: 6px;
            padding: 1.5rem;
            position: relative;
        }
        .code-block::before {
            content: "";
            position: absolute;
            top: 10px;
            left: 10px;
            width: 12px;
            height: 12px;
            border-radius: 50%;
            background-color: #ff5f56;
            box-shadow: 20px 0 0 #ffbd2e, 40px 0 0 #27c93f;
        }
        .card-hover:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .drop-cap:first-letter {
            float: left;
            font-size: 3.5em;
            line-height: 0.8;
            margin-right: 0.1em;
            margin-bottom: 0.1em;
            color: #6e8efb;
            font-weight: 700;
        }
    </style>
</head>
<body class="antialiased">
    <!-- Hero Section -->
    <header class="hero-gradient text-white py-20 px-4 sm:px-6 lg:px-8">
        <div class="max-w-5xl mx-auto text-center">
            <div class="inline-block px-4 py-2 mb-6 bg-white bg-opacity-20 rounded-full backdrop-filter backdrop-blur-sm">
                <span class="text-sm font-medium">Spring 框架</span>
            </div>
            <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold mb-6 font-serif">
                Spring 拦截链
            </h1>
            <p class="text-xl md:text-2xl max-w-3xl mx-auto opacity-90 mb-8">
                <span class="drop-cap">I</span>nterceptor Chain 是一种用于在请求处理的生命周期中执行自定义逻辑的机制，为开发者提供了强大的请求处理控制能力
            </p>
            <div class="flex justify-center space-x-4">
                <a href="#implementation" class="px-6 py-3 bg-white text-indigo-600 rounded-lg font-medium hover:bg-opacity-90 transition-all duration-300 transform hover:scale-105">
                    <i class="fas fa-code mr-2"></i>实现机制
                </a>
                <a href="#scenarios" class="px-6 py-3 bg-transparent border-2 border-white text-white rounded-lg font-medium hover:bg-white hover:bg-opacity-10 transition-all duration-300 transform hover:scale-105">
                    <i class="fas fa-lightbulb mr-2"></i>应用场景
                </a>
            </div>
        </div>
    </header>

    <!-- Main Content -->
    <main class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
        <!-- Introduction Section -->
        <section class="mb-20">
            <div class="bg-white rounded-2xl shadow-md p-8">
                <h2 class="text-3xl font-bold mb-6 text-gray-800 flex items-center">
                    <span class="w-8 h-8 bg-indigo-100 rounded-full flex items-center justify-center mr-4">
                        <i class="fas fa-info-circle text-indigo-600"></i>
                    </span>
                    拦截链的核心概念
                </h2>
                <div class="prose max-w-none text-gray-600">
                    <p>Spring 拦截链（Interceptor Chain）是一种用于在请求处理的生命周期中执行自定义逻辑的机制。它允许开发者在 Spring 应用程序的不同阶段插入代码，比如在请求被处理之前、请求处理后、视图渲染之前等。</p>
                    <p>这种机制在实现通用功能（如日志记录、权限检查、性能监控等）时非常有用，它提供了一种非侵入式的方式来增强应用程序的功能。</p>
                </div>
            </div>
        </section>

        <!-- Implementation Mechanism -->
        <section id="implementation" class="mb-20">
            <h2 class="text-3xl font-bold mb-10 text-gray-800 border-b pb-4 flex items-center">
                <span class="w-8 h-8 bg-blue-100 rounded-full flex items-center justify-center mr-4">
                    <i class="fas fa-cogs text-blue-600"></i>
                </span>
                Spring 拦截链的实现机制
            </h2>

            <!-- 1. Interceptor Definition -->
            <div class="mb-16">
                <div class="flex items-center mb-6">
                    <div class="flex-shrink-0 bg-indigo-500 text-white rounded-full w-10 h-10 flex items-center justify-center mr-4">
                        <span class="font-bold">1</span>
                    </div>
                    <h3 class="text-2xl font-semibold text-gray-800">拦截器的定义</h3>
                </div>
                <div class="prose max-w-none text-gray-600 mb-6">
                    <p>在 Spring 中，拦截器通常实现 <code>HandlerInterceptor</code> 接口。该接口定义了三个主要的方法，分别在请求处理的不同阶段被调用。</p>
                </div>
                <div class="code-block mb-6">
                    <pre class="overflow-x-auto"><code>public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在请求处理之前执行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 在请求处理之后，视图渲染之前执行
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 在请求完成后执行
    }
}</code></pre>
                </div>
                <div class="grid md:grid-cols-3 gap-6">
                    <div class="bg-white p-6 rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300">
                        <div class="text-blue-600 mb-3">
                            <i class="fas fa-play-circle text-2xl"></i>
                        </div>
                        <h4 class="font-bold text-lg mb-2">preHandle</h4>
                        <p class="text-gray-600">该方法在请求处理之前被调用。返回 <code>true</code> 表示继续处理请求，返回 <code>false</code> 表示请求被终止。</p>
                    </div>
                    <div class="bg-white p-6 rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300">
                        <div class="text-purple-600 mb-3">
                            <i class="fas fa-pause-circle text-2xl"></i>
                        </div>
                        <h4 class="font-bold text-lg mb-2">postHandle</h4>
                        <p class="text-gray-600">该方法在请求处理之后（视图渲染之前）被调用，可以修改模型和视图信息。</p>
                    </div>
                    <div class="bg-white p-6 rounded-xl shadow-md hover:shadow-lg transition-shadow duration-300">
                        <div class="text-green-600 mb-3">
                            <i class="fas fa-stop-circle text-2xl"></i>
                        </div>
                        <h4 class="font-bold text-lg mb-2">afterCompletion</h4>
                        <p class="text-gray-600">该方法在请求完成之后（视图渲染之后）被调用，可以进行资源清理等操作。</p>
                    </div>
                </div>
            </div>

            <!-- 2. Interceptor Configuration -->
            <div class="mb-16">
                <div class="flex items-center mb-6">
                    <div class="flex-shrink-0 bg-indigo-500 text-white rounded-full w-10 h-10 flex items-center justify-center mr-4">
                        <span class="font-bold">2</span>
                    </div>
                    <h3 class="text-2xl font-semibold text-gray-800">配置拦截器</h3>
                </div>
                <div class="prose max-w-none text-gray-600 mb-6">
                    <p>拦截器需要通过 <code>WebMvcConfigurer</code> 配置到 Spring MVC 中。可以通过重写 <code>addInterceptors</code> 方法将拦截器注册到 Spring MVC。</p>
                </div>
                <div class="code-block">
                    <pre class="overflow-x-auto"><code>@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/**"); // 配置拦截的路径
    }
}</code></pre>
                </div>
                <div class="mt-6 bg-blue-50 p-4 rounded-lg flex items-start">
                    <div class="flex-shrink-0 mr-3 text-blue-600">
                        <i class="fas fa-info-circle"></i>
                    </div>
                    <p class="text-blue-800">这里使用了 <code>InterceptorRegistry</code> 来添加自定义的拦截器，并可以配置拦截的 URL 模式。</p>
                </div>
            </div>

            <!-- 3. Execution Order -->
            <div class="mb-16">
                <div class="flex items-center mb-6">
                    <div class="flex-shrink-0 bg-indigo-500 text-white rounded-full w-10 h-10 flex items-center justify-center mr-4">
                        <span class="font-bold">3</span>
                    </div>
                    <h3 class="text-2xl font-semibold text-gray-800">拦截链的执行顺序</h3>
                </div>
                <div class="prose max-w-none text-gray-600 mb-8">
                    <p>当请求到达 Spring MVC 的 DispatcherServlet 时，拦截器链按照添加的顺序依次执行：</p>
                </div>
                
                <div class="mermaid mb-8">
                    sequenceDiagram
                        participant Client
                        participant Interceptor1
                        participant Interceptor2
                        participant Controller
                        participant View
                        
                        Client->>Interceptor1: 请求到达
                        Interceptor1->>Interceptor1: preHandle
                        Interceptor1->>Interceptor2: 传递请求
                        Interceptor2->>Interceptor2: preHandle
                        Interceptor2->>Controller: 传递请求
                        Controller->>View: 处理请求
                        View->>Interceptor2: 返回响应
                        Interceptor2->>Interceptor2: postHandle
                        Interceptor2->>Interceptor1: 传递响应
                        Interceptor1->>Interceptor1: postHandle
                        Interceptor1->>Client: 返回响应
                        Note right of Interceptor1: afterCompletion调用顺序与preHandle相反
                </div>
                
                <div class="grid md:grid-cols-2 gap-6">
                    <div class="bg-white p-6 rounded-xl shadow-md">
                        <h4 class="font-bold text-lg mb-4 flex items-center">
                            <span class="w-6 h-6 bg-blue-100 rounded-full flex items-center justify-center mr-3 text-blue-600">
                                <i class="fas fa-arrow-right"></i>
                            </span>
                            请求处理阶段
                        </h4>
                        <ul class="space-y-3 text-gray-600">
                            <li class="flex items-start">
                                <span class="flex-shrink-0 w-5 h-5 bg-blue-100 text-blue-600 rounded-full flex items-center justify-center mr-3 mt-0.5">
                                    <i class="fas fa-check text-xs"></i>
                                </span>
                                <span><code>preHandle</code>：拦截器链中的 <code>preHandle</code> 方法按添加顺序执行。如果任何拦截器的 <code>preHandle</code> 方法返回 <code>false</code>，请求会被终止</span>
                            </li>
                            <li class="flex items-start">
                                <span class="flex-shrink-0 w-5 h-5 bg-blue-100 text-blue-600 rounded-full flex items-center justify-center mr-3 mt-0.5">
                                    <i class="fas fa-check text-xs"></i>
                                </span>
                                <span>如果 <code>preHandle</code> 方法返回 <code>true</code>，请求会传递到目标处理器（Controller）</span>
                            </li>
                        </ul>
                    </div>
                    <div class="bg-white p-6 rounded-xl shadow-md">
                        <h4 class="font-bold text-lg mb-4 flex items-center">
                            <span class="w-6 h-6 bg-purple-100 rounded-full flex items-center justify-center mr-3 text-purple-600">
                                <i class="fas fa-arrow-left"></i>
                            </span>
                            响应处理阶段
                        </h4>
                        <ul class="space-y-3 text-gray-600">
                            <li class="flex items-start">
                                <span class="flex-shrink-0 w-5 h-5 bg-purple-100 text-purple-600 rounded-full flex items-center justify-center mr-3 mt-0.5">
                                    <i class="fas fa-check text-xs"></i>
                                </span>
                                <span><code>postHandle</code>：在处理器执行完成后，<code>postHandle</code> 方法按添加顺序执行，可以修改 <code>ModelAndView</code></span>
                            </li>
                            <li class="flex items-start">
                                <span class="flex-shrink-0 w-5 h-5 bg-purple-100 text-purple-600 rounded-full flex items-center justify-center mr-3 mt-0.5">
                                    <i class="fas fa-check text-xs"></i>
                                </span>
                                <span><code>afterCompletion</code>：请求完成后，<code>afterCompletion</code> 方法按添加顺序执行，通常用于清理资源</span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </section>

        <!-- Application Scenarios -->
        <section id="scenarios" class="mb-20">
            <h2 class="text-3xl font-bold mb-10 text-gray-800 border-b pb-4 flex items-center">
                <span class="w-8 h-8 bg-green-100 rounded-full flex items-center justify-center mr-4">
                    <i class="fas fa-lightbulb text-green-600"></i>
                </span>
                应用场景
            </h2>
            
            <div class="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
                <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover transition-all duration-300">
                    <div class="bg-blue-100 p-6 flex items-center justify-center">
                        <i class="fas fa-clipboard-list text-blue-600 text-4xl"></i>
                    </div>
                    <div class="p-6">
                        <h3 class="font-bold text-xl mb-3">日志记录</h3>
                        <p class="text-gray-600">记录请求的开始和结束时间、请求的 URL、响应状态等，便于系统监控和问题排查</p>
                    </div>
                </div>
                
                <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover transition-all duration-300">
                    <div class="bg-purple-100 p-6 flex items-center justify-center">
                        <i class="fas fa-shield-alt text-purple-600 text-4xl"></i>
                    </div>
                    <div class="p-6">
                        <h3 class="font-bold text-xl mb-3">权限控制</h3>
                        <p class="text-gray-600">检查用户权限，决定是否允许继续处理请求，实现细粒度的访问控制</p>
                    </div>
                </div>
                
                <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover transition-all duration-300">
                    <div class="bg-green-100 p-6 flex items-center justify-center">
                        <i class="fas fa-tachometer-alt text-green-600 text-4xl"></i>
                    </div>
                    <div class="p-6">
                        <h3 class="font-bold text-xl mb-3">性能监控</h3>
                        <p class="text-gray-600">监控请求处理时间，记录性能数据，帮助优化系统响应速度</p>
                    </div>
                </div>
                
                <div class="bg-white rounded-xl shadow-md overflow-hidden card-hover transition-all duration-300">
                    <div class="bg-yellow-100 p-6 flex items-center justify-center">
                        <i class="fas fa-edit text-yellow-600 text-4xl"></i>
                    </div>
                    <div class="p-6">
                        <h3 class="font-bold text-xl mb-3">请求修改</h3>
                        <p class="text-gray-600">修改请求和响应数据，如添加默认值或自定义 headers，增强请求处理能力</p>
                    </div>
                </div>
            </div>
        </section>

        <!-- Best Practices -->
        <section class="mb-20">
            <h2 class="text-3xl font-bold mb-10 text-gray-800 border-b pb-4 flex items-center">
                <span class="w-8 h-8 bg-orange-100 rounded-full flex items-center justify-center mr-4">
                    <i class="fas fa-star text-orange-600"></i>
                </span>
                最佳实践与注意事项
            </h2>
            
            <div class="bg-white rounded-xl shadow-md overflow-hidden">
                <div class="p-8">
                    <div class="flex items-start mb-6">
                        <div class="flex-shrink-0 mr-4 text-orange-500">
                            <i class="fas fa-exclamation-triangle text-xl"></i>
                        </div>
                        <div>
                            <h3 class="text-xl font-bold mb-2 text-gray-800">性能考虑</h3>
                            <p class="text-gray-600">拦截器会在每个请求的处理路径上执行，过多的拦截器或复杂的拦截逻辑可能会影响系统性能。建议：</p>
                            <ul class="list-disc pl-5 mt-3 space-y-2 text-gray-600">
                                <li>避免在拦截器中执行耗时操作（如数据库查询）</li>
                                <li>合理使用路径匹配，避免不必要的拦截</li>
                                <li>考虑使用缓存来提高性能</li>
                            </ul>
                        </div>
                    </div>
                    
                    <div class="flex items-start mb-6">
                        <div class="flex-shrink-0 mr-4 text-blue-500">
                            <i class="fas fa-random text-xl"></i>
                        </div>
                        <div>
                            <h3 class="text-xl font-bold mb-2 text-gray-800">执行顺序管理</h3>
                            <p class="text-gray-600">拦截器的执行顺序很重要，特别是当多个拦截器之间存在依赖关系时。可以通过 <code>order</code> 方法明确指定顺序：</p>
                            <div class="code-block mt-3">
                                <pre class="overflow-x-auto"><code>@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new AuthInterceptor()).order(1);
    registry.addInterceptor(new LogInterceptor()).order(2);
}</code></pre>
                            </div>
                        </div>
                    </div>
                    
                    <div class="flex items-start">
                        <div class="flex-shrink-0 mr-4 text-green-500">
                            <i class="fas fa-project-diagram text-xl"></i>
                        </div>
                        <div>
                            <h3 class="text-xl font-bold mb-2 text-gray-800">与过滤器的区别</h3>
                            <p class="text-gray-600">拦截器(Interceptor)与过滤器(Filter)的区别：</p>
                            <div class="mt-3 overflow-x-auto">
                                <table class="min-w-full divide-y divide-gray-200">
                                    <thead class="bg-gray-50">
                                        <tr>
                                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">特性</th>
                                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">拦截器</th>
                                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">过滤器</th>
                                        </tr>
                                    </thead>
                                    <tbody class="bg-white divide-y divide-gray-200">
                                        <tr>
                                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">所处层级</td>
                                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">Spring MVC框架层</td>
                                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">Servlet容器层</td>
                                        </tr>
                                        <tr>
                                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">依赖</td>
                                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">依赖Spring容器</td>
                                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">不依赖Spring</td>
                                        </tr>
                                        <tr>
                                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">执行时机</td>
                                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">Controller方法前后</td>
                                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">Servlet处理前后</td>
                                        </tr>
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>
    </main>

    <!-- Footer -->
    <footer class="bg-gray-900 text-gray-300 py-12">
        <div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
            <div class="flex flex-col md:flex-row justify-between items-center">
                <div class="mb-6 md:mb-0">
                    <h3 class="text-xl font-bold text-white mb-2">技术小馆</h3>
                    <p class="text-gray-400">专注于技术分享与知识传播</p>
                </div>
                <div>
                    <a href="http://www.yuque.com/jtostring" class="text-gray-300 hover:text-white transition-colors duration-300 flex items-center">
                        <i class="fas fa-external-link-alt mr-2"></i>
                        http://www.yuque.com/jtostring
                    </a>
                </div>
            </div>
            <div class="border-t border-gray-800 mt-8 pt-8 text-center text-gray-500 text-sm">
                &copy; 2023 技术小馆. 保留所有权利.
            </div>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            },
            securityLevel: 'loose'
        });
        
        // 平滑滚动
        document.querySelectorAll('a[href^="#"]').forEach(anchor => {
            anchor.addEventListener('click', function (e) {
                e.preventDefault();
                document.querySelector(this.getAttribute('href')).scrollIntoView({
                    behavior: 'smooth'
                });
            });
        });
    </script>
</body>
</html>
```